﻿#ifndef __INC_QG_MATH_H__
#define __INC_QG_MATH_H__

#if _MSC_VER
#pragma once
#endif

#include <float.h>

namespace _math
{
	//
	inline kuint GetMipmapLevels(kuint size)
	{
		kuint cnt = 1;
		while (size >>= 1)
			cnt++;
		return cnt;
	}

	inline kuint GetMipmapLevels(kuint width, kuint height)
	{
		return GetMipmapLevels(K_MAX(width, height));
	}

	inline kuint GetMipmapLevels(kuint width, kuint height, kuint depth)
	{
		return GetMipmapLevels(K_MAX(width, height), depth);
	}

	//
	inline kint OptimizeTextureSize(kint value, bool req_po2, kint maximum)
	{
		kint i;

		if (!req_po2)
			i = value;
		else
		{
			for (i = 1; i < value; i <<= 1)
				;
		}

		if (maximum > 0 && i > maximum)
			i = maximum;

		return i;
	}

	//
	inline tpl::Mat4 BuildIrrchtTextureMatrix(float rrad,
		const tpl::Vec2& rcenter, const tpl::Vec2& translate, const tpl::Vec2& scale)
	{
		float c, s;
		k_sincos(rrad, &s, &c);

		return tpl::Mat4(
			c * scale.x,
			s * scale.y,
			0.0f,
			0.0f,

			-s * scale.x,
			c * scale.y,
			0.0f,
			0.0f,

			c * scale.x * rcenter.x + -s * rcenter.y + translate.x,
			s * scale.y * rcenter.x + c * rcenter.y + translate.y,
			1.0f,
			0.0f,

			0.0f,
			0.0f,
			0.0f,
			1.0f);
	}

	//
	inline tpl::Mat4 BuildGlTextureMatrix(const tpl::Mat4& m)
	{
		tpl::Mat4 o;

		o._m[0] = m._m[0];
		o._m[1] = m._m[1];
		o._m[2] = 0.f;
		o._m[3] = 0.f;

		o._m[4] = m._m[4];
		o._m[5] = m._m[5];
		o._m[6] = 0.f;
		o._m[7] = 0.f;

		o._m[8] = 0.f;
		o._m[9] = 0.f;
		o._m[10] = 1.f;
		o._m[11] = 0.f;

		o._m[12] = m._m[8];
		o._m[13] = m._m[9];
		o._m[14] = 0.f;
		o._m[15] = 1.f;

		return o;
	}

	// global
	namespace Global
	{
		K_ANY_CONST kQd TexCoord = {0.0f, 0.0f, 1.0f, 1.0f};
		K_ANY_CONST kQd MaximumClip = {FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX};
	}
}

#endif	// __INC_QG_MATH_H__
